#include"data.hpp"
#include"httplib.h"
#include"Util.hpp"
namespace aod{
    #define WWWROOT "./www"
    #define VIDEO_ROOT "/video/"
    #define IMAGE_ROOT "/image/"
    aom::TableVideo* tb_video=nullptr;
    using namespace httplib;
    using std::string;
    using std::cout;
    using std::endl;
    class Server{
        private:
            int _port;
            httplib::Server _srv;
        private:
            static void Insert(const httplib::Request& req,httplib::Response& rsp){
                if(req.has_file("name")==false||req.has_file("info")==false||req.has_file("video")==false||req.has_file("image")==false)
                {
                    cout<<"ser:21 error"<<endl;
                    if(req.has_file("name")==false)
                    cout<<"name error"<<endl;
                    if(req.has_file("info")==false)
                    cout<<"info error"<<endl;
                    if(req.has_file("video")==false)
                    cout<<"video info error"<<endl;
                    if(req.has_file("image")==false)
                    cout<<"image info error"<<endl;
                    rsp.status=400;
                    rsp.body=R"({"result":false, "reason":"上传数据信息错误"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                MultipartFormData name=req.get_file_value("name");      //视频名称
                MultipartFormData info=req.get_file_value("info");      //视频介绍
                MultipartFormData video=req.get_file_value("video");    //视频文件
                MultipartFormData image=req.get_file_value("image");    //图片文件
                //MultipartFormData {name(视频名称),content_type,filename(数据原始名称),content(内容)}
                std::string video_name=name.content;
                string video_info=info.content;
                 // ./www/image/变形金刚a.jpg
                string root=WWWROOT;
                string  video_path=root;video_path+=VIDEO_ROOT;video_path+=name.filename+video.filename;
                string image_path=root;image_path+=IMAGE_ROOT;image_path+=name.filename+image.filename;
                if(FileUtil(video_path).SetContent(video.content)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"视频文件存储失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                if(FileUtil(image_path).SetContent(image.content)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"图片文件存储失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                Json::Value video_json;
                int prefix_size=root.size();
                video_json["name"]=video_name;
                video_json["info"]=video_info;
                video_json["video"]=video_path.substr(prefix_size);   // /video/变形金刚robot.mp4
                video_json["image"]=image_path.substr(prefix_size);      
                if(tb_video->Insert(video_json)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"数据库新增数据失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }  
            }
            static void Delete(const httplib::Request& req,httplib::Response& rsp){
                //1.获取删除视频ID
                int video_id=stoi(req.matches[1]);
                //2.删除视频文件
                Json::Value video;
                if(tb_video->SelectOne(video_id,&video)==false)
                {
                     rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"不存在视频信息"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                string root=WWWROOT;
                string video_path=root+video["video"].asString();
                string image_path=root+video["image"].asString();
                remove(video_path.c_str());
                remove(image_path.c_str());
                //3.删除数据库信息
                if(tb_video->Delete(video_id)==false)
                {
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"删除数据库信息失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
            }
            static void Update(const httplib::Request& req,httplib::Response& rsp){
                //1.获取要修改的视频信息  a.视频ID  b.修改后的信息
                int video_id=stoi(req.matches[1]);
                Json::Value video;
                if(JsonUtil::UnSerialize(req.body,&video)==false)
                {
                    rsp.status=400;
                    rsp.body=R"({"result":false, "reason":"新的视频信息格式解析失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                //2.修改数据库数据
                if(tb_video->Update(video_id,video)==false){
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"修改数据库信息失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
            }
            static void SelectOne(const httplib::Request& req,httplib::Response& rsp){
                //1。获取视频ID
                int viedo_id=stoi(req.matches[1]);
                //2.再数据库中查询指定视频信息
                Json::Value video;
                if(tb_video->SelectOne(viedo_id,&video)==false){
                    rsp.status=500;
                    rsp.body=R"({"result":false, "reason":"查询数据库指定视频信息失败"})";
                    rsp.set_header("Content-Type","application/json");
                    return;
                }
                //3.组织响应正文--JSON格式的字符串
                JsonUtil::Serialize(video,&rsp.body);
                rsp.set_header("Content-Type","application/json");
                return;
            }
            static void SelectAll(const httplib::Request& req,httplib::Response& rsp){
                // /video & /video?search="关键字"
                bool select_flag=true;  //默认查询所有
                string serach_key;
                if(req.has_param("search")==true){
                    select_flag=false;
                    serach_key=req.get_param_value("search");
                }
                Json::Value videos;
                if(select_flag==true){
                    tb_video->SelectAll(&videos);
                }
                else{
                    tb_video->SelectLike(serach_key,&videos);
                }
                JsonUtil::Serialize(videos,&rsp.body);
                rsp.set_header("Content-Type","application/json");
                return;
            }
        public:
            Server(int port):_port(port){}
            bool RunModule(){
                //1.初始化操作--初始化数据管理模块，创建指定的目录
                tb_video=new aom::TableVideo();
                FileUtil(WWWROOT).CreateDirectory();
                std::string video_real_path=WWWROOT;
                video_real_path+=VIDEO_ROOT;
                FileUtil(video_real_path.c_str()).CreateDirectory();
                std::string image_real_path=WWWROOT;
                image_real_path+=IMAGE_ROOT;
                FileUtil(image_real_path.c_str()).CreateDirectory();
                //2.搭建http服务器。开始运行
                //a.设置静态资源根目录
                _srv.set_mount_point("/",WWWROOT);
                //b.添加请求-处理函数映射关系
                _srv.Post("/video",Insert); //上传
                _srv.Delete("/video/(\\d+)",Delete);
                _srv.Put("/video/(\\d+)",Update);   //修改数据
                _srv.Get("/video/(\\d+)",SelectOne);
                _srv.Get("/video/",SelectAll);
                //3.启动服务器
                _srv.listen("0.0.0.0",_port);
                return true;
            };
    };
}